﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace DarwinIsDead.Traits {
    public class RandomBurst : Trait {
        private List<Bullet> bullets;
        private int currentBullet;

        private int baseDamage;
        private int baseBurstSize;

        private int burst;
        private int burstSize;
        private float burstTime;
        private float burstCounter;

        private float fireTime;
        private float fireCounter;
        private float fireDirection;

        private float recoilSpeed;
        private float recoilTime;
        private float recoilCounter;
        private Vector2 recoilVector;

        private Random random;
        private SpriteFont font;

        public RandomBurst(Zombie owner, World world) 
            : base(owner, world){
            bullets = new List<Bullet>();
            baseDamage = 1;
            baseBurstSize = 4;

            currentBullet = 0;

            burst = 0;
            burstSize = baseBurstSize;
            burstTime = 2f; // Zombie fires every 2 seconds
            burstCounter = 0f;

            fireTime = 0.125f; // .125 seconds between shots
            fireCounter = 0f;
            fireDirection = 0f;

            recoilSpeed = 200f;
            recoilTime = 0.125f;
            recoilCounter = 0f;
            recoilVector = new Vector2();

            random = new Random();

            font = World.Game.Content.Load<SpriteFont>("Fonts\\Courier New");
        }

        public override void Initialize() {
            // Populate our gun mag and add it to the World, so the bullets
            // can be updated and be collided
            for (int i = 0; i < 10; i++) {
                Bullet bullet = new Bullets.Linear(World, 5, 800f, 500f, false);
                bullet.NotifyDamage = Owner.AddDamage;
                bullets.Add(bullet);
                World.AddEntity(bullet);
            }

            Level = 1;
        }

        public override object Clone() {
            RandomBurst ret = new RandomBurst(Owner, World);
            ret.Level = Level;
            return ret;
        }

        public override void Dispose() {
            // Remove all bullets from the world, so we're not wasting
            // cycles checking for collisions against dead objects
            foreach (Bullet bullet in bullets) {
                World.RemoveEntity(bullet);
            }
        }

        protected override void AdjustLevel(int level) {
            foreach (Bullet bullet in bullets) {
                bullet.Damage = level * baseDamage;
            }

            burstSize = level * baseBurstSize;
        }

        protected override void InternalUpdate(GameTime gameTime) {
            float dt = gameTime.ElapsedGameTime.Milliseconds / 1000f;

            if (burst > 0) {
                // If we're shooting
                fireCounter += dt;  // Wait a bit between shots
                if (fireCounter > fireTime) {
                    fireCounter = 0f;
                    // Fire a bullet
                    if (!bullets[currentBullet].Active) {
                        // Fire in a random direction
                        fireDirection = (float)(random.NextDouble() * 2.0 * Math.PI);
                        bullets[currentBullet].Fire(Owner.Position, fireDirection);
                        burst--;

                        // Recoil
                        recoilCounter = recoilTime;
                    }
                    currentBullet = (currentBullet + 1) % bullets.Count;
                }
            } else {
                // Wait a bit between shooting bursts
                burstCounter += dt;
                if (burstCounter > burstTime) {
                    burst = burstSize;   // Let it loose
                    burstCounter = 0f;
                }
            }

            if (recoilCounter > 0f) {
                Owner.Move(recoilSpeed * dt * (float)Math.Cos((float)Math.PI + fireDirection),
                           recoilSpeed * dt * (float)Math.Sin((float)Math.PI + fireDirection));
                recoilCounter -= dt;
            }
        }

        protected override void InternalDraw(SpriteBatch spriteBatch, Color color) {
            spriteBatch.DrawString(font, "Burst: " + burst, Owner.Position, color);
        }

    }
}
